package com.itany.crawler;

import com.itany.utils.Log;
import org.apache.http.NoHttpResponseException;
import org.apache.http.conn.ConnectTimeoutException;

import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

public class Main {
    public static String testDataPath = "C:\\projects3";
    //    public static String testDataPath = "/home/soft01/桌面/projects";
    static int maxThreadNum = 100;
    public static boolean enableProxy = true;

    public static Urls urls = new Urls();

    public static int currentThreadNum = 0;

    public static boolean runnable = true; //  设置当前爬虫状态 ,false 退出


    public static void main(String[] args) throws InterruptedException, IOException {
        start();
        for (int i = 0; i < maxThreadNum && runnable; i++) {
            Thread thread = new Thread(() -> {
                while (!urls.isEmpty() && runnable) {
                    UrlBaseHandle handle = urls.pop();
                    try {
                        handle.handle(urls);
                        Thread.sleep(500);
                    }

//                    catch (NullPointerException e) {
//                        e.printStackTrace(); // 空指针不能忍
//                        List<String> log = new LinkedList<>();
//                        log.add(e.getMessage());
//                        log.add(handle.url);
//                        try {
//                            Files.write(Paths.get(Main.testDataPath, "log.txt"), log,
//                                    StandardOpenOption.CREATE, StandardOpenOption.APPEND);
//                        } catch (IOException ioException) {
//                            ioException.printStackTrace();
//                        }
//                        break;
//                    }

                    catch (SocketException | ConnectTimeoutException | SocketTimeoutException | CustomException | NoHttpResponseException e) {
                        System.out.println("错误信息 :" + e.getMessage());
                        urls.add(handle);
                    } catch (Exception e) {
                        e.printStackTrace();
                        urls.add(handle);
                    }
                }
//                System.out.println("当前线程名 :" + Thread.currentThread().getName());
                decNumOfThread();
                save();
            }, UUID.randomUUID().toString());

            thread.start();
            addNumOfThread();
            Thread.sleep(1000);
        }

        System.out.println("over");
    }


    public static void start() {

        urls.load();
        if (urls.size() == 0) {
            urls.add(new IndexHandle(enableProxy));
        }

//        urls.add(new SecondHandle(null, false));
//        urls.add(new ThirdHandle(null, true));
        while (!urls.isEmpty()) {
            if (!runnable) {
                save();
                return;
            }
            UrlBaseHandle handle = urls.pop();
            try {
                handle.handle(urls);
                Thread.sleep(500);
            } catch (NullPointerException e) {
                System.out.println("==========空指针");
                e.printStackTrace();
                break;
            } catch (Exception e) {
                urls.add(handle);
                System.out.println("===========" + e.getMessage());
            }

            if (urls.size() > 50) {
                System.out.println("=========== 开启多线程");
                break;
            }
        }

    }

    private static synchronized void addNumOfThread() {
        currentThreadNum++;
    }


    private static synchronized void decNumOfThread() {
        currentThreadNum--;
    }

    private static void save() {
        if (currentThreadNum > 0) {
            return;
        }

        //最后一个线程 做保存操作
        urls.save();
        Log.logErr("保存且退出");
        System.out.println("保存且退出");
    }
}
